#include "general.h"

#include <buola/image/cfont.h>
#include <buola/widgets/cbutton.h>
#include <buola/image/cgc.h>
#include <buola/gui/cimagematrix.h>
#include <buola/gui/cicon.h>
#include <buola/widgets/ctoolbar.h>
#include <buola/widgets/ctabbox.h>
#include <buola/widgets/csliderbox.h>
#include <buola/widgets/cscrollbar.h>
#include <buola/widgets/coptionbox.h>
#include <buola/widgets/clabelbox.h>
#include <buola/widgets/ceditbox.h>
#include <buola/widgets/ccombobox.h>
#include <buola/widgets/ccheckbox.h>
#include <buola/gui/cconfig.h>
#include <buola/io/cresourcefinder.h>
#include <buola/widgets/cmenubar.h>
#include <buola/image/cgradient.h>
#include <buola/widgets/crulerbox.h>
#include <buola/widgets/cstatusbar.h>
#include <buola/widgets/cprogressbar.h>
#include <buola/widgets/cnumbox.h>
#include <buola/image/format.h>

namespace buola { namespace gui {

CCairoTheme::CCairoTheme()
    :   mInit(false)
    ,   mDecoInit(false)
{
    mInit=false;
}

CCairoTheme::~CCairoTheme()
{
}

img::CPicture CCairoTheme::GetImage(const std::string &pName)
{
    return img::CPicture(io::data_finder().FindFile("buola/images/"+pName));
}

img::CPicture CCairoTheme::CreateDecoButton(float pHue,const img::CPicture &pBase)
{
    img::CImage_hsv32f lHSV(pBase.Size());

    convert_pixels(view_rgba8(pBase.Image()),lHSV);

    for(int y=0;y<lHSV.Height();++y)
    {
        auto lIt=lHSV.Row(y).begin();

        for(int x=0;x<lHSV.Width();++x)
        {
            float lHue=lIt[x][0]+pHue;

            if(lHue<0.0f)
                lHue+=1.0f;
            else if(lHue>1.0f)
                lHue-=1.0f;

            lIt[x][0]=lHue;
        }
    }

    img::CImage_rgb8 lNew(lHSV.Size());
    convert_pixels(lHSV,lNew);

    return img::CPicture(std::move(lNew));
}

void CCairoTheme::InitDeco()
{
    if(mDecoInit) return;

    mDeco.mTL=GetImage("kollide/tl.png");
    mDeco.mT=GetImage("kollide/t.png");
    mDeco.mTR=GetImage("kollide/tr.png");
    mDeco.mL=GetImage("kollide/l.png");
    mDeco.mR=GetImage("kollide/r.png");
    mDeco.mBL=GetImage("kollide/bl.png");
    mDeco.mB=GetImage("kollide/b.png");
    mDeco.mBR=GetImage("kollide/br.png");

    mDeco.mBaseButton[DECO_STATE_NORMAL]=GetImage("kollide/x.png");
    mDeco.mBaseButton[DECO_STATE_HOVER]=GetImage("kollide/xh.png");
    mDeco.mBaseButton[DECO_STATE_PRESSED]=GetImage("kollide/xp.png");
    mDeco.mBaseButton[DECO_STATE_INACTIVE]=GetImage("kollide/xi2.png");

    for(int i=0;i<DECO_STATECOUNT;i++)
    {
        mDeco.mButtons[DECO_BUTTON_MIN][i]=CreateDecoButton(0.45,
                                            mDeco.mBaseButton[i]);
        mDeco.mButtons[DECO_BUTTON_MAX][i]=CreateDecoButton(-0.80,
                                            mDeco.mBaseButton[i]);
        mDeco.mButtons[DECO_BUTTON_CLOSE][i]=CreateDecoButton(-0.45,
                                            mDeco.mBaseButton[i]);
        mDeco.mButtons[DECO_BUTTON_DOCK][i]=CreateDecoButton(0.0,
                                            mDeco.mBaseButton[i]);
    }

    mDecoInit=true;
}

void CCairoTheme::Init()
{
    if(mInit) return;

    mColors.mBase=gConfig.mColors.Get(L"liquid_base");
    mColors.mInactive=gConfig.mColors.Get(L"liquid_inactive");
    mColors.mText=gConfig.mColors.Get(L"liquid_text");
    mColors.mClose=gConfig.mColors.Get(L"micro_close");
    mColors.mSelected=gConfig.mColors.Get(L"selection_back");

    mListBackground=GetImage("menu_back.png");
    mDecoButtonGreen=GetImage("decobutton-green.png");
    mDecoButtonGrey=GetImage("decobutton-grey.png");
    mDecoButtonBlue=GetImage("decobutton-blue.png");
    mDecoButtonYellow=GetImage("decobutton-yellow.png");
    mDecoButtonRed=GetImage("decobutton-red.png");
    CCairoHelper::InitMatrixPool(L"button-base",mRoundButton);
    CCairoHelper::InitMatrixPool(L"rectbutton",mRectButton);
    CCairoHelper::InitMatrixPool(L"rectbutton",mRotRectButton,false,true);
    CCairoHelper::InitMatrixPool(L"combo",mCombo);
    CCairoHelper::InitMatrixPool(L"combo",mRotCombo,false,true);
    CCairoHelper::InitMatrixPool(L"tab",mTab);
    CCairoHelper::InitMatrixPool(L"tab",mTabInvert,true);

    img::CPicture lImage=CCairoHelper::LoadImage(L"tab");
    ///\todo
    mTabBase.Init(lImage);//->ExtractImage(CPoint_d(40,21),CSize_i(4,6)));

    mBack.Init(CCairoHelper::LoadImage(L"clear_fill_small"));

    mCheckBoxOn.Init(CCairoHelper::LoadImage(L"checkboxdown"));
    mCheckBoxOff.Init(CCairoHelper::LoadImage(L"checkbox"));

    mOptionBoxOn.Init(CCairoHelper::LoadImage(L"radio_down"));
    mOptionBoxOff.Init(CCairoHelper::LoadImage(L"radio"));

    mHSliderArrow.Init(CCairoHelper::LoadImage(L"sliderarrow"));
    lImage=CCairoHelper::LoadImage(L"sliderarrow");
    ///\todo
    //lImage->Rotate90();
    mVSliderArrow.Init(lImage);

    mVBack.Init(COLOR_MATRIX_3V,CCairoHelper::LoadImage2(L"sbgroove_top"),
                                CCairoHelper::LoadImage2(L"sbgroove_mid"),
                                CCairoHelper::LoadImage2(L"sbgroove_btm"));
    mVSlider.Init(COLOR_MATRIX_3V,CCairoHelper::LoadImage2(L"sbslider_top"),
                                CCairoHelper::LoadImage2(L"sbslider_mid"),
                                CCairoHelper::LoadImage2(L"sbslider_btm"));
    mVISlider.Init(COLOR_MATRIX_3V,CCairoHelper::LoadImage2(L"sbslider_top"),
                                CCairoHelper::LoadImage2(L"sbIslider_mid"),
                                CCairoHelper::LoadImage2(L"sbslider_btm"));
    mVButton.Init(CCairoHelper::LoadImage(L"sb_subadd"));

    img::CImage_rgba8 lT=CCairoHelper::LoadImage2(L"sbgroove_top");
    img::CImage_rgba8 lM=CCairoHelper::LoadImage2(L"sbgroove_mid");
    img::CImage_rgba8 lB=CCairoHelper::LoadImage2(L"sbgroove_btm");
    ///\todo
    //lT->Rotate90();
    //lM->Rotate90();
    //lB->Rotate90();
    mHBack.Init(COLOR_MATRIX_3H,std::move(lT),std::move(lM),std::move(lB));

    lT=CCairoHelper::LoadImage2(L"sbslider_top");
    lM=CCairoHelper::LoadImage2(L"sbslider_mid");
    lB=CCairoHelper::LoadImage2(L"sbslider_btm");
    ///\todo
    //lT->Rotate90();
    //lM->Rotate90();
    //lB->Rotate90();
    mHSlider.Init(COLOR_MATRIX_3H,std::move(lT),std::move(lM),std::move(lB));

    lT=CCairoHelper::LoadImage2(L"sbslider_top");
    lM=CCairoHelper::LoadImage2(L"sbIslider_mid");
    lB=CCairoHelper::LoadImage2(L"sbslider_btm");
    ///\todo
    //lT->Rotate90();
    //lM->Rotate90();
    //lB->Rotate90();
    mHISlider.Init(COLOR_MATRIX_3H,std::move(lT),std::move(lM),std::move(lB));

    img::CPicture lSB=CCairoHelper::LoadImage(L"sb_subadd");
    ///\todo
    //lB->Rotate90();
    mHButton.Init(lSB);

    mFont=img::CFont::GetStock(L"control");
    mMenuFont=img::CFont::GetStock(L"menu");
    mMenuBoldFont=img::CFont::GetStock(L"menubold");
    mBoldFont=img::CFont::GetStock(L"controlbold");
    mSmallFont=img::CFont::GetStock(L"small");
    mFont90=img::CFont::GetStock(L"control_90");

    mMicroButton.Init(CCairoDecoHelper::LoadImage(L"button_milk"));
    mMicroButtonHover.Init(CCairoDecoHelper::LoadImage(L"button_jaguar"));
    mMicroButtonDown.Init(CCairoDecoHelper::LoadImage(L"button_jaguar_down"));
    mCloseIcon=CCairoDecoHelper::LoadImage(L"icon_close");

    mInit=true;

//    mShadow=CGaussianMap::GetMap()->GetShadow(0.50,1500,1500,mShadowSize);
//    mBlackPicture=CGaussianMap::GetMap()->GetSolid(true,1,0,0,0);
}

void CCairoTheme::DrawArrow(img::CGC *pGC,const CPoint_d &pC,EArrow pArrow)
{
    if(pArrow==ARROW_DOWN)
    {
        pGC->Path().MoveTo(CPoint_d(pC.x-2.5,pC.y-2.5));
        pGC->Path().LineTo(CPoint_d(pC.x+3.5,pC.y-2.5));
        pGC->Path().LineTo(CPoint_d(pC.x+0.5,pC.y+3.0));
        pGC->Path().Close();
    }
    else if(pArrow==ARROW_UP)
    {
        pGC->Path().MoveTo(CPoint_d(pC.x-2.5,pC.y+2.5));
        pGC->Path().LineTo(CPoint_d(pC.x+3.5,pC.y+2.5));
        pGC->Path().LineTo(CPoint_d(pC.x+0.5,pC.y-3.0));
        pGC->Path().Close();
    }
    else if(pArrow==ARROW_RIGHT)
    {
        pGC->Path().MoveTo(CPoint_d(pC.x-2.5,pC.y-2.5));
        pGC->Path().LineTo(CPoint_d(pC.x-2.5,pC.y+3.5));
        pGC->Path().LineTo(CPoint_d(pC.x+3.0,pC.y+0.5));
        pGC->Path().Close();
    }
    else if(pArrow==ARROW_LEFT)
    {
        pGC->Path().MoveTo(CPoint_d(pC.x+2.5,pC.y-2.5));
        pGC->Path().LineTo(CPoint_d(pC.x+2.5,pC.y+3.5));
        pGC->Path().LineTo(CPoint_d(pC.x-3.0,pC.y+0.5));
        pGC->Path().Close();
    }

    pGC->SetLineWidth(1.0);
    pGC->FillPath(true);
    pGC->StrokePath();

}

CPoint_d CCairoTheme::GetButtonTextPos(CButton *pB,const CRect_d &pR)
{
    CSize_d lSize;
    CPoint_d lReturn;

    if(pB->GetStyle()&BUTTON_TEXT)
    {
        img::PFont lFont=pB->GetStyle(CWidget::STYLE_SMALLFONT)?mSmallFont:mFont;
        lSize.x=lFont->GetWidth(pB->Caption());
        lSize.y=lFont->GetHeight();

        lReturn.x=(pR.w()-lSize.x-1)/2;
        lReturn.y=(pR.h()-lSize.y-1)/2;
    }
    else if(pB->GetStyle()&BUTTON_IMAGE)
    {
        lSize=pB->NormalImage().Size();
        lReturn={0,0};
    }
    else if(pB->GetStyle()&BUTTON_PICTURE)
    {
        lSize=pB->NormalImage().Size();
        lReturn.x=(pR.w()-lSize.x-1)/2;
        lReturn.y=(pR.h()-lSize.y-1)/2;
    }

    return lReturn;
}

void CCairoTheme::PrepareButton(CButton *pB)
{
    pB->SetBackNone();
    pB->SetPaintMode(CWindow::EPaintMode::NORMAL);
}

void CCairoTheme::DrawButton(img::CGC *pGC,CButton *pB,EDrawStyle)
{
    if(!mInit) Init();

    CSize_d lSize=pB->Size();
    
    pGC->SetSource(pB->Parent()->BackColor());
    pGC->Paint();

    if(pB->GetStyle(BUTTON_MICRO))
    {
        if(pB->Pressed())
        {
            pGC->DrawImage({0,0},mMicroButtonDown.Get(mColors.mClose));
        }
        else if(pB->PointerInside())
        {
            pGC->DrawImage({0,0},mMicroButtonHover.Get(mColors.mClose));
        }
        else
        {
            pGC->DrawImage({0,0},mMicroButton.Get(mColors.mInactive));
        }

        pGC->DrawImage({0,0},mCloseIcon);
    }
    else
    {
#if 1   //old style buttons
        if(!pB->GetStyle(BUTTON_IMAGE))
        {
            double lH=lSize.y;
            double lR=lH/2;
            pGC->Path().Reset();
            pGC->Path().Arc(CPoint_d(lR,lR),lR,M_PI/2,3*M_PI/2);
            pGC->Path().LineTo(CPoint_d(lSize.x-lR,0));
            pGC->Path().Arc(CPoint_d(lSize.x-lR,lR),lR,3*M_PI/2,5*M_PI/2);
            pGC->Path().Close();
            pGC->ClipPath();
            img::CLinearGradient lPattern(CPoint_d(0,0),CPoint_d(0,lSize.y));
            lPattern.AddStop(img::rgb8(0,136,199),0.0);
            lPattern.AddStop(img::rgb8(24,116,163),1.0);
            pGC->SetSource(lPattern);
            pGC->Paint();

            pGC->Path().Reset();
            pGC->Path().Arc(CPoint_d(lR,0),lR,M_PI/2,3*M_PI/2);
            pGC->Path().LineTo(CPoint_d(lSize.x-lR,-lR));
            pGC->Path().Arc(CPoint_d(lSize.x-lR,0),lR,-M_PI/2,M_PI/2);
            pGC->Path().Close();
            img::CLinearGradient lPattern2(CPoint_d(0,0),CPoint_d(0,lR));
            lPattern2.AddStop(img::rgb8(129,196,229),0.0);
            lPattern2.AddStop(img::rgb8(82,172,218),0.2);
            lPattern2.AddStop(img::rgb8(49,147,197),0.9);
            lPattern2.AddStop(img::rgb8(39,140,191),1.0);
            pGC->SetSource(lPattern2);
            pGC->FillPath();
        }
#else
        CImageMatrix *lUsed=nullptr;

        if(pB->GetStyle(BUTTON_SMALL))
        {
            if(pB->IsPressed())
            {
                lUsed=mRectButton.Get(mColors.mBase.GetDarker(10));
            }
            else if(pB->IsInside())
            {
                lUsed=mRectButton.Get(mColors.mBase);
            }
            else
            {
                lUsed=mRectButton.Get(mColors.mInactive);
            }
        }
        else if(!pB->GetStyle(BUTTON_IMAGE))
        {
            if(pB->IsPressed())
            {
                lUsed=mRoundButton.Get(mColors.mBase.GetDarker(10));
            }
            else if(pB->IsInside())
            {
                lUsed=mRoundButton.Get(mColors.mBase);
            }
            else
            {
                lUsed=mRoundButton.Get(mColors.mInactive);
            }
        }

        if(lUsed)
            lUsed->Draw(pGC,pB->GetRect(),CImageMatrix::REPEATONE);
#endif
        if(pB->GetStyle()&BUTTON_TEXT)
        {
            if(pB->GetStyle(CWidget::STYLE_DISABLED))
                pGC->SetSource(gConfig.mColors.Get(L"disabled_text"));
            else
                pGC->SetSource(mColors.mText);
            if(pB->GetStyle(CWidget::STYLE_SMALLFONT))
            {
                pGC->SetFont(mSmallFont);
            }
            else if(pB->HasFocus())
            {
                pGC->SetFont(mBoldFont);
            }
            else
            {
                pGC->SetFont(mFont);
            }
            pGC->SetStockFont(L"nice");
            pGC->SetSource(img::rgb8(24,116,163));
            pGC->DrawText({lSize.x/2-2,lSize.y/2-2},pB->Caption(),img::ETextPos::CENTER);
            pGC->SetSource({1.0,1.0,1.0});
            pGC->DrawText({lSize.x/2-1,lSize.y/2-1},pB->Caption(),img::ETextPos::CENTER);
        }
        else
        {
            img::CPicture lUsedImage;
            if(pB->Pressed())
            {
                lUsedImage=pB->PressedImage();
                if(!lUsedImage) lUsedImage=pB->NormalImage();
            }
            else if(pB->PointerInside())
            {
                lUsedImage=pB->HoverImage();
                if(!lUsedImage) lUsedImage=pB->NormalImage();
            }
            else
            {
                lUsedImage=pB->NormalImage();
            }

            pGC->DrawImage(GetButtonTextPos(pB,CRect_d({0,0},lSize))+1,lUsedImage);
        }
    }
}

void CCairoTheme::DrawCheckBox(img::CGC *pGC,CCheckBox *pC,EDrawStyle)
{
    if(!mInit) Init();

    CSize_d lSize=pC->Size();
    
    img::PFont lFont=pC->GetStyle(CWidget::STYLE_SMALLFONT)?mSmallFont:mFont;

    pGC->SetSource(pC->Parent()->BackColor());
    pGC->Paint();
    pGC->SetSource(mColors.mText);
    pGC->SetFont(lFont);
    CPoint_d lCenter(lSize.x/2,lSize.y/2);
    pGC->DrawText(CPoint_d(24,lCenter.y-lFont->GetHeight()/2),pC->Caption());

    if(pC->IsChecked())
        pGC->DrawImage(CPoint_d(5,lCenter.y-mCheckBoxOn.GetSize().y/2),
                    mCheckBoxOn.Get(mColors.mBase));
    else
        pGC->DrawImage(CPoint_d(5,lCenter.y-mCheckBoxOn.GetSize().y/2),
                    mCheckBoxOff.Get(mColors.mInactive));
}

void CCairoTheme::DrawComboBox(img::CGC *pGC,CComboBox *pC,
                        EDrawStyle pFlags)
{
    if(!mInit) Init();
    
    CSize_d lSize=pC->Size();

    if(pC->GetStyle(CWidget::STYLE_INBAR))
    {
        CRect_d lTLRect;///\todo =pC->GetTopLevelRect();
        img::CLinearGradient lBasePattern(CPoint_d(0,-lTLRect.t-22),CPoint_d(0,-lTLRect.t-22+100));
        lBasePattern.AddStop(img::rgb8(197,197,197),0.00);
        lBasePattern.AddStop(img::rgb8(170,170,170),0.56);
        lBasePattern.AddStop(img::rgb8(170,170,170),1.0);
        pGC->SetSource(lBasePattern);
    }
    else
    {
        pGC->SetSource(pC->Parent()->BackColor());
    }
    pGC->Paint();
    CRect_d lLeft(0,0,lSize.x-lSize.y,lSize.y);
    CRect_d lRight(lSize.x-lSize.y,0,lSize.x,lSize.y);

    if(pC->GetStyle(CWidget::STYLE_SMALLFONT))
    {
        pGC->DrawImageTiled(lRight,{0,0},(pFlags&DRAW_UP)?
                        mBack.Get(mColors.mBase):mBack.GetBase());
    }
    else
    {
        mCombo.Get(mColors.mInactive)->Draw(pGC,lLeft,CImageMatrix::NORIGHT);
        mCombo.Get(mColors.mBase)->Draw(pGC,lRight,CImageMatrix::NOLEFT);
    }
    pGC->SetSource(img::rgba8(40,40,40,180));
    DrawArrow(pGC,CPoint_d((lRight.l+lRight.r)/2-1,(lRight.t+lRight.b)/2),ARROW_DOWN);
    if(!pC->GetStyle(CB_FREEEDIT))
    {
        img::PFont lFont=pC->GetStyle(CWidget::STYLE_SMALLFONT)?mSmallFont:mFont;

        pGC->SetSource(mColors.mText);
        pGC->SetFont(lFont);
        CPoint_d lCenter(lSize.x/2,lSize.y/2);
        pGC->DrawText(CPoint_d(10,lCenter.y-lFont->GetHeight()/2),
                                pC->GetCaption());
    }
}

void CCairoTheme::PrepareEditBox(CEditBox *pE)
{
    pE->SetBackColor({1.0,1.0,1.0});
    pE->SetPaintMode(CWindow::EPaintMode::NORMAL);
}

void CCairoTheme::DrawEditBox(img::CGC *pGC,CEditBox *pE,EDrawStyle)
{
    if(!mInit) Init();
    
    CSize_d lSize=pE->Size();

    if(pE->mSelStart>=0&&pE->mSelEnd>=0&&pE->mSelStart<pE->mSelEnd)
                    //some text selected
    {
        pGC->SetSource(mColors.mSelected);
        ///\todo scroll
        pE->GetTextLayout().FillBack(img::CTextLayout::SCursor(pE->mSelStart),
                        img::CTextLayout::SCursor(pE->mSelEnd),
                        pE->mTextPos/*-pE->GetScrollPos()*/,pGC);
    }

    pGC->SetSource(mColors.mText);
    ///\todo scroll
    pE->GetTextLayout().Draw(pE->mTextPos/*-pE->GetScrollPos()*/,pGC);

    if(!pE->GetStyle(CWidget::STYLE_NOBORDER))
    {
        const double lRadius=7;

        if(pE->GetStyle(CWidget::STYLE_INBAR))
        {
            CRect_d lTLRect;///\todo=pE->GetTopLevelRect();
            img::CLinearGradient lBasePattern(CPoint_d(0,-lTLRect.t-22),CPoint_d(0,-lTLRect.t-22+100));
            lBasePattern.AddStop(img::rgb8(197,197,197),0.00);
            lBasePattern.AddStop(img::rgb8(170,170,170),0.56);
            lBasePattern.AddStop(img::rgb8(170,170,170),1.0);
            pGC->SetSource(lBasePattern);
        }
        else
        {
            pGC->SetSource(pE->Parent()->BackColor());
        }
        pGC->Path().MoveTo(0,0);
        pGC->Path().LineTo(lRadius,0);
        pGC->Path().Arc(CPoint_d(lRadius,lRadius),lRadius,-M_PI/2,-M_PI);
        pGC->Path().LineTo(0,lSize.y-lRadius);
        pGC->Path().Arc(CPoint_d(lRadius,lSize.y-lRadius),lRadius,M_PI,M_PI/2);
        pGC->Path().LineTo(0,lSize.y);
        pGC->Path().Close();
        pGC->FillPath();
        pGC->Path().MoveTo(lSize.x,0);
        pGC->Path().LineTo(lSize.x-lRadius,0);
        pGC->Path().Arc(CPoint_d(lSize.x-lRadius,lRadius),lRadius,-M_PI/2,0);
        pGC->Path().LineTo(lSize.x,lSize.y-lRadius);
        pGC->Path().Arc(CPoint_d(lSize.x-lRadius,lSize.y-lRadius),lRadius,0,M_PI/2);
        pGC->Path().LineTo(lSize.x,lSize.y);
        pGC->Path().Close();
        pGC->FillPath();

        if(pE->HasFocus())
        {
//          pGC->SetSource(gConfig.mColors.Get(L"selection_back"));
//          pGC->SetLineWidth(3.0);
//          pGC->Path().RoundRect(pR.Offset(1.0),lRadius-1.5);
//          pGC->StrokePath();

            CRect_d lR({0,0},lSize);
            pGC->SetSource(img::rgb8(254,192,80));
            pGC->SetLineWidth(1.0);
            pGC->Path().RoundRect(lR.Offset(2.5),lRadius-2.5);
            pGC->StrokePath();
            pGC->SetSource(img::rgb8(248,198,110));
            pGC->Path().RoundRect(lR.Offset(1.5),lRadius-1.5);
            pGC->StrokePath();
            pGC->SetSource(img::rgb8(242,204,140));
            pGC->Path().RoundRect(lR.Offset(0.5),lRadius-0.5);
            pGC->StrokePath();

/*
            pGC->SetSource(img::rgb8(80,192,255));
            pGC->SetLineWidth(1.0);
            pGC->Path().RoundRect(pR.Offset(2.5),lRadius-2.5);
            pGC->StrokePath();
            pGC->SetSource(img::rgb8(128,202,244));
            pGC->Path().RoundRect(pR.Offset(1.5),lRadius-1.5);
            pGC->StrokePath();
            pGC->SetSource(img::rgb8(176,213,234));
            pGC->Path().RoundRect(pR.Offset(0.5),lRadius-0.5);
            pGC->StrokePath();
*/
        }
        else
        {
            CRect_d lR({0,0},lSize);
            pGC->SetLineWidth(0.5);
            pGC->Path().RoundRect(lR.Offset(0.5),lRadius-0.5);
            pGC->SetSource(img::rgb8(120,120,120));
            pGC->StrokePath();
        }
    }

    if(pE->mCursorOn)
        DrawCursor(pGC,pE->mCursorPos);
}

void CCairoTheme::DrawLabelBox(img::CGC *pGC,CLabelBox *pL,EDrawStyle)
{
    if(!mInit) Init();

    pGC->SetSource(pL->Parent()->BackColor());
    pGC->Paint();

    img::PFont lFont=pL->GetStyle(CWidget::STYLE_SMALLFONT)?mSmallFont:mFont;

    CSize_d lLabelSize=pL->Size();
    CSize_d lSize(mFont->GetWidth(pL->GetCaption()),lFont->GetHeight());
    CPoint_d lPoint;

    if(pL->GetStyle(LBL_VERT))
    {
        pGC->SetFont(mFont90);

        if(pL->GetStyle(LBL_RIGHT))
            lPoint.y=lSize.x;
        else if(pL->GetStyle(LBL_CENTER))
            lPoint.y=(lLabelSize.y+lSize.x)/2;
        else
            lPoint.y=lLabelSize.y;

        if(pL->GetStyle(LBL_BOTTOM))
            lPoint.x=lLabelSize.x;
        else if(pL->GetStyle(LBL_TOP))
            lPoint.x=lSize.y;
        else
            lPoint.x=(lLabelSize.x+lSize.y)/2;
    }
    else
    {
        pGC->SetFont(lFont);

        if(pL->GetStyle(LBL_RIGHT))
            lPoint.x=lLabelSize.x-lSize.x;
        else if(pL->GetStyle(LBL_CENTER))
            lPoint.x=(lLabelSize.x-lSize.x)/2;
        else
            lPoint.x=0;

        if(pL->GetStyle(LBL_BOTTOM))
            lPoint.y=lLabelSize.y-lSize.y;
        else if(pL->GetStyle(LBL_TOP))
            lPoint.y=0;
        else
            lPoint.y=(lLabelSize.y-lSize.y)/2;
    }

    pGC->SetSource(mColors.mText);
    pGC->DrawText(lPoint,pL->GetCaption());
}

void CCairoTheme::DrawListBox(img::CGC*,CListBox*,EDrawStyle)
{
    if(!mInit) Init();
}

void CCairoTheme::PrepareMenuBar(CMenuBar *pM)
{
    if(pM->GetStyle()&CMenuBar::STYLE_POPUP)
    {
        ///\todo it should be in popup or something!!
//        pM->SetOpacity(0.92);
        pM->SetBackColor({1.0,1.0,1.0});
    }
}

void CCairoTheme::DrawMenuBar(img::CGC *pGC,CMenuBar *pM,EDrawStyle)
{
    if(!mInit) Init();

    if(!(pM->GetStyle()&CMenuBar::STYLE_POPUP))
    {
        CRect_d lTLRect;///\todo=pM->GetTopLevelRect();
        img::CLinearGradient lPattern(CPoint_d(0,-lTLRect.t-22),CPoint_d(0,-lTLRect.t-22+100));
        lPattern.AddStop(img::rgb8(197,197,197),0.00);
        lPattern.AddStop(img::rgb8(170,170,170),0.56);
        lPattern.AddStop(img::rgb8(170,170,170),1.0);
        pGC->SetSource(lPattern);

//      pGC->SetOperator(OP_SRC);
        pGC->Paint();
    }
}

void CCairoTheme::DrawNumBox(img::CGC *pGC,CNumBox *pN,EDrawStyle pFlags)
{
    if(!mInit) Init();

    CSize_d lSize=pN->Size();
    
    CRect_d lUp(lSize.x-12,0,lSize.x,lSize.y/2);
    CRect_d lDown(lSize.x-12,lSize.y/2,lSize.x,lSize.y);

    CPoint_d lEP(lSize.x-7,floor(lSize.y/2));

    pGC->SetLineWidth(1.0);

    pGC->Path().MoveTo(CPoint_d(lEP.x-2.5,lEP.y+1.0));
    pGC->Path().LineTo(CPoint_d(lEP.x+3.5,lEP.y+1.0));
    pGC->Path().LineTo(CPoint_d(lEP.x+0.5,lEP.y+6.5));
    pGC->Path().Close();

    if(pFlags&DRAW_DOWN)
        pGC->SetSource(img::rgb8(120,120,120));
    else
        pGC->SetSource({0.0,0.0,0.0});

    pGC->FillPath();

    pGC->Path().MoveTo(CPoint_d(lEP.x-2.5,lEP.y-1.0));
    pGC->Path().LineTo(CPoint_d(lEP.x+3.5,lEP.y-1.0));
    pGC->Path().LineTo(CPoint_d(lEP.x+0.5,lEP.y-6.5));
    pGC->Path().Close();

    if(pFlags&DRAW_UP)
        pGC->SetSource(img::rgb8(120,120,120));
    else
        pGC->SetSource({0.0,0.0,0.0});

    pGC->FillPath();
}

void CCairoTheme::DrawOptionBox(img::CGC *pGC,COptionBox *pO,EDrawStyle)
{
    if(!mInit) Init();

    pGC->SetSource(pO->Parent()->BackColor());
    pGC->Paint();

    img::PFont lFont=pO->GetStyle(CWidget::STYLE_SMALLFONT)?mSmallFont:mFont;

    pGC->SetSource(mColors.mText);
    pGC->SetFont(lFont);
    CSize_d lSize=pO->Size();
    CPoint_d lCenter(lSize.x/2,lSize.y/2);
    pGC->DrawText(CPoint_d(24,lCenter.y-lFont->GetHeight()/2),pO->GetCaption());

    if(pO->IsChecked())
        pGC->DrawImage(CPoint_d(5,lCenter.y-mOptionBoxOn.GetSize().y/2),
                        mOptionBoxOn.Get(mColors.mBase));
    else
        pGC->DrawImage(CPoint_d(5,lCenter.y-mOptionBoxOn.GetSize().y/2),
                        mOptionBoxOff.Get(mColors.mInactive));
}

void CCairoTheme::PrepareRulerBox(CRulerBox *pR)
{
    pR->SetBackNone();
    pR->SetPaintMode(CWindow::EPaintMode::NORMAL);
}

void CCairoTheme::DrawRulerBox(img::CGC *pGC,CRulerBox *pR,EDrawStyle)
{
    CSize_d lSize=pR->Size();
    
    img::CLinearGradient lPattern(CPoint_d(0,0),CPoint_d(0,lSize.y-1));
    lPattern.AddStop(img::rgb8(255,255,255),0.00);
    lPattern.AddStop(img::rgb8(255,255,255),0.15);
    lPattern.AddStop(img::rgb8(224,224,224),0.5);
    lPattern.AddStop(img::rgb8(255,255,255),0.85);
    lPattern.AddStop(img::rgb8(255,255,255),1.0);
    pGC->SetSource(lPattern);
    pGC->Path().Rect({0,0},CSize_d(lSize.x,lSize.y-1));
    pGC->FillPath();
    pGC->SetLineWidth(1.0);
    pGC->Path().MoveTo(CPoint_d(0,lSize.y-0.5));
    pGC->Path().LineTo(CPoint_d(lSize.x,lSize.y-0.5));
    pGC->SetSource(img::rgb8(215,215,215));
    pGC->StrokePath();
}

void CCairoTheme::DrawProgressBar(img::CGC *pGC,CProgressBar *pP,EDrawStyle)
{
    if(!mInit) Init();

    CSize_d lBarSize=pP->Size();
    img::CLinearGradient lPattern(CPoint_d(0,1),CPoint_d(0,lBarSize.y-1));
    lPattern.AddStop(img::rgb8(183,205,134),0.0);
    lPattern.AddStop(img::rgb8(140,178,83),0.5);
    lPattern.AddStop(img::rgb8(108,144,47),0.5);
    lPattern.AddStop(img::rgb8(108,144,47),1.0);
    double lSize=lBarSize.x-2;
    double lCompleteEnd=1+round(lSize*pP->GetProgress());

    CRect_d lRect(1,1,lCompleteEnd,lBarSize.y-1);

    pGC->Path().Rect(lRect.TopLeft(),lRect.Size());
    pGC->SetSource(lPattern);
    pGC->FillPath();

    img::CLinearGradient lBackPattern(CPoint_d(0,1),CPoint_d(0,lBarSize.y-1));

    lBackPattern.AddStop(img::rgb8(203,203,203),0.0);
    lBackPattern.AddStop(img::rgb8(230,230,230),0.5);
    lBackPattern.AddStop(img::rgb8(230,230,230),1.0);

    pGC->Path().Rect(CPoint_d(lRect.r,lRect.t),CSize_d(lBarSize.x-1-lRect.r,lRect.h()));
    pGC->SetSource(lBackPattern);
    pGC->FillPath();

    pGC->Path().Rect(CPoint_d(0.5,0.5),CSize_d(lBarSize.x-1,lBarSize.y-1));
    pGC->SetSource(img::rgb8(160,160,160));
    pGC->StrokePath();
}

void CCairoTheme::PrepareScrollBar(CScrollBar *pS)
{
    pS->SetBackNone();
    pS->SetPaintMode(CWindow::EPaintMode::NORMAL);
}

void CCairoTheme::DrawScrollBar(img::CGC *pGC,CScrollBar *pS,EDrawStyle pF)
{
    pGC->SetLineWidth(1.0);
    img::CColor lColor(mColors.mInactive);
    CSize_d lSize=pS->Size();

    if(!mInit) Init();

    pGC->SetSource({0.15,0.15,0.15});

    //Background
    if(pS->GetStyle()&CScrollBar::STYLE_HORIZONTAL)
    {
        img::CPicture lButton=mHButton.Get(lColor);
        pGC->DrawImage(CPoint_d(0,0),lButton);
        mHBack.Get(lColor)->Draw(pGC,CRect_d(lButton.Size().x,0,lSize.x-lButton.Size().x,lSize.y));

        DrawScrollBarCursor(pGC,CRect_d(pS->GetCursorTop(),0,pS->GetCursorBottom(),lSize.y),false,pF&DRAW_HOVER);

        pGC->DrawImage(CPoint_d(lSize.x-lButton.Size().x,0),lButton);

        pGC->SetSource(img::rgba8(40,40,40,180));
        DrawArrow(pGC,CPoint_d((pS->GetBarTop())/2,lSize.y/2),ARROW_LEFT);
        DrawArrow(pGC,CPoint_d((lSize.x-pS->GetBarBottom())/2,lSize.y/2),ARROW_RIGHT);
    }
    else
    {
        img::CLinearGradient lBackPattern(CPoint_d(0,0),CPoint_d(lSize.x,0));
        lBackPattern.AddStop(img::rgb8(180,180,180),0.0);
        lBackPattern.AddStop(img::rgb8(251,251,251),2.0/3.0);
        lBackPattern.AddStop(img::rgb8(251,251,251),0.8);
        lBackPattern.AddStop(img::rgb8(237,237,237),1.0);
        pGC->SetSource(lBackPattern);
        pGC->Path().Rect({0,0},lSize);
        pGC->FillPath();

        img::CLinearGradient lButtonPattern(CPoint_d(0,0),CPoint_d(lSize.x,0));
        lButtonPattern.AddStop(img::rgb8(173,173,173),0.0);
        lButtonPattern.AddStop(img::rgb8(250,250,250),2.75/15.0);
        lButtonPattern.AddStop(img::rgb8(250,250,250),6.25/15.0);
        lButtonPattern.AddStop(img::rgb8(225,225,225),7.5/15.0);
        lButtonPattern.AddStop(img::rgb8(255,255,255),12.5/15.0);
        lButtonPattern.AddStop(img::rgb8(234,234,234),1.0);

        pGC->SetSource(lButtonPattern);
        pGC->Path().MoveTo(CPoint_d(0,0));
        pGC->Path().LineTo(CPoint_d(lSize.x,0));
        pGC->Path().LineTo(CPoint_d(lSize.x,lSize.x+lSize.x/2+3));
        pGC->Path().Arc(CPoint_d(lSize.x/2,lSize.x+lSize.x/2+3),lSize.x/2,0,M_PI);
        pGC->Path().Close();
        pGC->FillPath();
        pGC->SetSource(img::rgba8(0,0,0,50));
        pGC->Path().Arc(CPoint_d(lSize.x/2,lSize.x+lSize.x/2+3),lSize.x/2,-M_PI/6,-5*M_PI/6);
        pGC->StrokePath();

        pGC->SetSource(lButtonPattern);
        pGC->Path().MoveTo(CPoint_d(0,lSize.y));
        pGC->Path().LineTo(CPoint_d(lSize.x,lSize.y));
        pGC->Path().LineTo(CPoint_d(lSize.x,lSize.y-lSize.x-lSize.x/2-3));
        pGC->Path().Arc(CPoint_d(lSize.x/2,lSize.y-lSize.x-lSize.x/2-3),lSize.x/2,0,M_PI);
        pGC->Path().Close();
        pGC->FillPath();
        pGC->SetSource(img::rgba8(0,0,0,50));
        pGC->Path().Arc(CPoint_d(lSize.x/2,lSize.y-lSize.x-lSize.x/2-3),lSize.x/2,M_PI/6,5*M_PI/6);
        pGC->StrokePath();

        DrawScrollBarCursor(pGC,CRect_d(0,pS->GetCursorTop(),lSize.x,pS->GetCursorBottom()),true,pF&DRAW_HOVER);

        pGC->SetSource(img::rgba8(40,40,40,180));
        DrawArrow(pGC,CPoint_d(lSize.x/2,(pS->GetBarTop())/2),ARROW_UP);
        DrawArrow(pGC,CPoint_d(lSize.x/2,(lSize.y+pS->GetBarBottom())/2),ARROW_DOWN);
    }
}

void CCairoTheme::PrepareSliderBox(CSliderBox *pS)
{
    pS->SetBackNone();
}

void CCairoTheme::DrawSliderBox(img::CGC *pGC,CSliderBox *pS,EDrawStyle)
{
    if(!mInit) Init();

    CSize_d lSize=pS->Size();
    
    if(pS->GetStyle(CSliderBox::STYLE_HORIZONTAL))
    {
        pGC->SetSource(pS->Parent()->BackColor());
        pGC->Paint();
        pGC->SetLineWidth(1.0);
        double lYC=lSize.x/2-2+0.5;
        double lXL=GetSliderSize()/2;
        double lXR=lSize.x-GetSliderSize()/2;
        ///\todo putpixel
/*
        pGC->PutPixel(CPoint_d(lXL-2,lYC-2),img::rgb8(199,199,199));
        pGC->PutPixel(CPoint_d(lXL-1,lYC-2),img::rgb8(115,115,115));
        pGC->PutPixel(CPoint_d(lXL-2,lYC-1),img::rgb8(122,122,122));
        pGC->PutPixel(CPoint_d(lXL-1,lYC-1),img::rgb8(111,111,111));
        pGC->PutPixel(CPoint_d(lXL-2,lYC),img::rgb8(107,107,107));
        pGC->PutPixel(CPoint_d(lXL-1,lYC),img::rgb8(145,145,145));
        pGC->PutPixel(CPoint_d(lXL-2,lYC+1),img::rgb8(145,145,145));
        pGC->PutPixel(CPoint_d(lXL-1,lYC+1),img::rgb8(143,143,143));
        pGC->PutPixel(CPoint_d(lXL-2,lYC+2),img::rgb8(204,204,204));
        pGC->PutPixel(CPoint_d(lXL-1,lYC+2),img::rgb8(152,152,152));
        pGC->PutPixel(CPoint_d(lXR+2,lYC-2),img::rgb8(199,199,199));
        pGC->PutPixel(CPoint_d(lXR+1,lYC-2),img::rgb8(115,115,115));
        pGC->PutPixel(CPoint_d(lXR+2,lYC-1),img::rgb8(122,122,122));
        pGC->PutPixel(CPoint_d(lXR+1,lYC-1),img::rgb8(111,111,111));
        pGC->PutPixel(CPoint_d(lXR+2,lYC),img::rgb8(107,107,107));
        pGC->PutPixel(CPoint_d(lXR+1,lYC),img::rgb8(145,145,145));
        pGC->PutPixel(CPoint_d(lXR+2,lYC+1),img::rgb8(145,145,145));
        pGC->PutPixel(CPoint_d(lXR+1,lYC+1),img::rgb8(143,143,143));
        pGC->PutPixel(CPoint_d(lXR+2,lYC+2),img::rgb8(204,204,204));
        pGC->PutPixel(CPoint_d(lXR+1,lYC+2),img::rgb8(152,152,152));
*/
        pGC->Path().MoveTo(CPoint_d(lXL,lYC-2));
        pGC->Path().LineTo(CPoint_d(lXR+1,lYC-2));
        pGC->SetSource(img::rgb8(89,89,89));
        pGC->StrokePath();
        pGC->Path().MoveTo(CPoint_d(lXL,lYC-1));
        pGC->Path().LineTo(CPoint_d(lXR+1,lYC-1));
        pGC->SetSource(img::rgb8(127,127,127));
        pGC->StrokePath();
        pGC->Path().MoveTo(CPoint_d(lXL,lYC));
        pGC->Path().LineTo(CPoint_d(lXR+1,lYC));
        pGC->SetSource(img::rgb8(157,157,157));
        pGC->StrokePath();
        pGC->Path().MoveTo(CPoint_d(lXL,lYC+1));
        pGC->Path().LineTo(CPoint_d(lXR+1,lYC+1));
        pGC->SetSource(img::rgb8(165,165,165));
        pGC->StrokePath();
        pGC->Path().MoveTo(CPoint_d(lXL,lYC+2));
        pGC->Path().LineTo(CPoint_d(lXR+1,lYC+2));
        pGC->SetSource(img::rgb8(130,130,130));
        pGC->StrokePath();

        pGC->DrawImage(CPoint_d(pS->CalcPos()-GetSliderSize()/2,
                        (lSize.y-mHSliderArrow.GetSize().y)/2),
                        mHSliderArrow.Get(mColors.mBase));
    }
    else
    {
        DrawSeparationLine(pGC,CPoint_d(lSize.x/2-2,lSize.x+GetSliderSize()/2),
                  CPoint_d(lSize.x/2-2,lSize.y-GetSliderSize()/2));

        pGC->DrawImage(CPoint_d((lSize.x-mVSliderArrow.GetSize().x)/2,
                        pS->CalcPos()-GetSliderSize()/2),
                        mVSliderArrow.Get(mColors.mBase));
    }
}

void CCairoTheme::DrawStatusBar(img::CGC *pGC,CStatusBar *pS,EDrawStyle)
{
    if(!mInit) Init();

    CRect_d lTLRect;///\todo =pS->GetTopLevelRect();
    img::CLinearGradient lBasePattern(CPoint_d(0,-lTLRect.t-22),CPoint_d(0,-lTLRect.t-22+100));
    lBasePattern.AddStop(img::rgb8(197,197,197),0.00);
    lBasePattern.AddStop(img::rgb8(170,170,170),0.56);
    lBasePattern.AddStop(img::rgb8(170,170,170),1.0);
    pGC->SetSource(lBasePattern);
    pGC->Paint();
}

void CCairoTheme::PrepareTabBox(CTabBox *pT)
{
    if(pT->GetStyle(TABBOX_UNDERTB))
    {
        pT->SetBackColor(img::rgb8(140,140,140));
    }
    else if(pT->GetStyle(TABBOX_MENULIKE))
    {
        pT->SetBackColor(img::rgb8(232,232,232));
    }
    else
    {
        pT->SetBackColor(img::rgb8(170,170,170));
    }
    pT->SetPaintMode(CWindow::EPaintMode::NORMAL);
}

void CCairoTheme::DrawTabBox(img::CGC *pGC,const CRect_d &pR,CTabBox *pT,EDrawStyle pF)
{
    if(!mInit) Init();

    if(pT->GetStyle(TABBOX_UNDERTB))
    {
        pGC->Path().Rect(CPoint_d(pR.l,pR.t),CSize_d(pR.w(),8));
        pGC->SetSource(img::rgb8(170,170,170));
        pGC->FillPath();
        pGC->SetLineWidth(1.0);
        pGC->SetSource(img::rgb8(115,115,115));
        pGC->Path().MoveTo(CPoint_d(pR.l,pR.t+8.5));
        pGC->Path().LineTo(CPoint_d(pR.r,pR.t+8.5));
        pGC->StrokePath();
        pGC->SetSource(img::rgb8(182,182,182));
        pGC->Path().MoveTo(CPoint_d(pR.l,pR.b-1.5));
        pGC->Path().LineTo(CPoint_d(pR.r,pR.b-1.5));
        pGC->StrokePath();
        pGC->SetSource(img::rgb8(110,110,110));
        pGC->Path().MoveTo(CPoint_d(pR.l,pR.b-0.5));
        pGC->Path().LineTo(CPoint_d(pR.r,pR.b-0.5));
        pGC->StrokePath();

        if(pF&DRAW_LEFTARROW)
        {
            pGC->SetSource(img::rgba8(0,0,0,150));
            DrawArrow(pGC,CPoint_d(pR.l+5,(pR.t+pR.b)/2),ARROW_LEFT);
        }
        if(pF&DRAW_RIGHTARROW)
        {
            pGC->SetSource(img::rgba8(0,0,0,150));
            DrawArrow(pGC,CPoint_d(pR.r-5,(pR.t+pR.b)/2+3.0),ARROW_RIGHT);
        }
    }
    else if(pT->GetStyle(TABBOX_PREFERENCES))
    {
        img::CLinearGradient lPattern(CPoint_d(pR.l,pR.t),CPoint_d(pR.l,pR.b));
        lPattern.AddStop(img::rgb8(186,186,186),0.0);
        lPattern.AddStop(img::rgb8(150,150,150),1.0);
        pGC->SetSource(lPattern);
        pGC->Path().Rect(pR.TopLeft(),pR.Size());
        pGC->FillPath();
    }
    else if(pT->GetStyle(TABBOX_MENULIKE))
    {
    }
    else
    {
        pGC->SetSource(mColors.mText);

        CRect_d lR;

        if(pT->GetStyle(TABBOX_TOP))
            lR={pR.l,pR.b-5,pR.r,pR.b};
        else
            lR={pR.l,pR.t,pR.r,pR.t+5};

        pGC->Path().Rect(lR.TopLeft(),lR.Size());
        pGC->StrokePath();
        pGC->DrawImageTiled(CRect_d(lR.l+1,lR.t+1,lR.r-1,lR.b-1),CPoint_d(lR.l+1,lR.t+1),
                        mTabBase.Get(mColors.mBase));
    }
}

void CCairoTheme::DrawTabBoxItem(img::CGC *pGC,const CRect_d &pR,CTabBox *pT,
                            CTabBoxItem *pI,EDrawStyle pF)
{
    if(!mInit) Init();

    img::PFont lFont=pT->GetStyle(CWidget::STYLE_SMALLFONT)?mSmallFont:mFont;

    if(pT->GetStyle(TABBOX_UNDERTB))
    {
        if(pF&DRAW_SELECTED)
        {
            pGC->Path().MoveTo(CPoint_d(pR.l,pR.t+8));
            pGC->Path().LineTo(CPoint_d(pR.l,pR.b-8));
            pGC->Path().Arc(CPoint_d(pR.l+3,pR.b-8),3,M_PI,M_PI/2);
            pGC->Path().LineTo(CPoint_d(pR.r-3,pR.b-5));
            pGC->Path().Arc(CPoint_d(pR.r-3,pR.b-8),3,M_PI/2,0);
            pGC->Path().LineTo(CPoint_d(pR.r,pR.t+8));
            pGC->Path().Close();
            pGC->SetSource(img::rgb8(170,170,170));
            pGC->FillPath();
            pGC->Path().MoveTo(CPoint_d(pR.l+0.5,pR.t+8));
            pGC->Path().LineTo(CPoint_d(pR.l+0.5,pR.b-8));
            pGC->Path().Arc(CPoint_d(pR.l+3.5,pR.b-8.5),3,M_PI,M_PI/2);
            pGC->Path().LineTo(CPoint_d(pR.r-3.5,pR.b-5.5));
            pGC->Path().Arc(CPoint_d(pR.r-3.5,pR.b-8.5),3,M_PI/2,0);
            pGC->Path().LineTo(CPoint_d(pR.r-0.5,pR.t+8));
            pGC->SetSource(img::rgb8(105,105,105));
            pGC->StrokePath();
        }

        pGC->SetSource(mColors.mText);
        pGC->SetFont(lFont);
        if(pI->mPoints)
        {
            pGC->DrawText(CPoint_d(pR.l+6,pR.t+13),pI->mText.substr(0,pI->mVisibleText)+L"...");
        }
        else
        {
            pGC->DrawText(CPoint_d(pR.l+6,pR.t+13),pI->mText);
        }

        CPoint_d lCenter(pR.r-12,pR.t+21);

        if(0)
        {
            pGC->DrawImage(lCenter-7,mDecoButtonRed);
            pGC->SetSource(img::rgba8(0,0,0,200));
        }
        else
        {
            pGC->SetSource(img::rgba8(0,0,0,100));
            pGC->Path().Reset();
            pGC->Path().Arc(lCenter,6);
            pGC->SetLineWidth(0.5);
            pGC->StrokePath();
        }

        pGC->Path().MoveTo(CPoint_d(lCenter.x-3,lCenter.y-3));
        pGC->Path().LineTo(CPoint_d(lCenter.x+3,lCenter.y+3));
        pGC->Path().MoveTo(CPoint_d(lCenter.x-3,lCenter.y+3));
        pGC->Path().LineTo(CPoint_d(lCenter.x+3,lCenter.y-3));
        pGC->SetLineWidth(2.0);
        pGC->StrokePath();
        pGC->SetLineWidth(1.0);
    }
    else if(pT->GetStyle(TABBOX_MENULIKE))
    {
        CRect_d lR(pR.l,pR.t+11,pR.r,pR.b-11);
        img::CLinearGradient lPattern(CPoint_d(lR.l,lR.t),CPoint_d(lR.l,lR.b));
        if(pF&DRAW_SELECTED)
        {
            lPattern.AddStop(img::rgb8(233,237,248),0.0);
            lPattern.AddStop(img::rgb8(187,213,240),0.1);
            lPattern.AddStop(img::rgb8(155,195,235),0.35);
            lPattern.AddStop(img::rgb8(112,173,235),0.4);
            lPattern.AddStop(img::rgb8(139,197,255),0.6);
            lPattern.AddStop(img::rgb8(193,245,255),1.0);
        }
        else
        {
            lPattern.AddStop(img::rgb8(253,253,253),0.0);
            lPattern.AddStop(img::rgb8(243,243,243),0.1);
            lPattern.AddStop(img::rgb8(235,235,235),0.35);
            lPattern.AddStop(img::rgb8(220,220,220),0.4);
            lPattern.AddStop(img::rgb8(255,255,255),0.8);
            lPattern.AddStop(img::rgb8(255,255,255),1.0);
        }

        pGC->SetSource(lPattern);
        pGC->Path().Rect(lR.TopLeft(),lR.Size());
        pGC->FillPath();
        pGC->SetLineWidth(1.0);
        pGC->Path().MoveTo(CPoint_d(lR.l,lR.t-0.5));
        pGC->Path().LineTo(CPoint_d(lR.r,lR.t-0.5));
        pGC->SetSource(img::rgb8(120,120,120));
        pGC->StrokePath();
        pGC->Path().MoveTo(CPoint_d(lR.l,lR.b+0.5));
        pGC->Path().LineTo(CPoint_d(lR.r,lR.b+0.5));
        pGC->SetSource(img::rgb8(85,85,85));
        pGC->StrokePath();
        if(pF&DRAW_LEFT)
        {
            pGC->Path().Reset();
            pGC->Path().Arc(CPoint_d(lR.l,lR.b-3),3,M_PI/2,M_PI);
            pGC->Path().LineTo(CPoint_d(lR.l-3,lR.t+3));
            pGC->Path().Arc(CPoint_d(lR.l,lR.t+3),3,M_PI,-M_PI/2);
            pGC->Path().Close();
            pGC->SetSource(lPattern);
            pGC->FillPath();
            pGC->Path().Reset();
            pGC->Path().Arc(CPoint_d(lR.l,lR.b-3),3,M_PI/2,M_PI);
            pGC->Path().LineTo(CPoint_d(lR.l-3,lR.t+3));
            pGC->Path().Arc(CPoint_d(lR.l,lR.t+3),3,M_PI,-M_PI/2);
            pGC->SetSource(img::rgb8(85,85,85));
            pGC->StrokePath();

        }
        if(pF&DRAW_RIGHT)
        {
            pGC->Path().Reset();
            pGC->Path().Arc(CPoint_d(lR.r,lR.t+3),3,-M_PI/2,0);
            pGC->Path().LineTo(CPoint_d(lR.r+3,lR.b-3));
            pGC->Path().Arc(CPoint_d(lR.r,lR.b-3),3,0,M_PI/2);
            pGC->Path().Close();
            pGC->SetSource(lPattern);
            pGC->FillPath();
            pGC->Path().Reset();
            pGC->Path().Arc(CPoint_d(lR.r,lR.t+3),3,-M_PI/2,0);
            pGC->Path().LineTo(CPoint_d(lR.r+3,lR.b-3));
            pGC->Path().Arc(CPoint_d(lR.r,lR.b-3),3,0,M_PI/2);
            pGC->SetSource(img::rgb8(85,85,85));
            pGC->StrokePath();

        }
        else
        {
            pGC->Path().MoveTo(CPoint_d(lR.r-0.5,lR.t));
            pGC->Path().LineTo(CPoint_d(lR.r-0.5,lR.b));
            pGC->SetSource(img::rgba8(0,0,0,20));
            pGC->StrokePath();
        }

        pGC->SetSource(mColors.mText);
        pGC->SetFont(lFont);
        pGC->DrawText(CPoint_d(lR.l+9,lR.t+3),pI->mText);
    }
    else if(pT->GetStyle(TABBOX_PREFERENCES))
    {
        CRect_d lR(pR.l,pR.t,pR.r,pR.b-1);

        if(pF&DRAW_SELECTED)
        {
            img::CLinearGradient lMainPattern(CPoint_d(lR.l,lR.t),CPoint_d(lR.l,lR.b));
            lMainPattern.AddStop(img::rgb8(186,186,186),0.0);
            lMainPattern.AddStop(img::rgb8(139,139,139),0.5);
            lMainPattern.AddStop(img::rgb8(150,150,150),1.0);
            pGC->SetSource(lMainPattern);
            pGC->Path().Rect(CPoint_d(lR.l+2,lR.t),CSize_d(lR.w()-4,lR.h()));
            pGC->FillPath();
            img::CLinearGradient lPattern2(CPoint_d(lR.l,lR.t),CPoint_d(lR.l,lR.b));
            lPattern2.AddStop(img::rgb8(186,186,186),0.0);
            lPattern2.AddStop(img::rgb8(85,85,85),0.5);
            lPattern2.AddStop(img::rgb8(150,150,150),1.0);
            pGC->SetLineWidth(1.0);
            pGC->SetSource(lPattern2);
            pGC->Path().MoveTo(CPoint_d(lR.l+0.5,lR.t));
            pGC->Path().LineTo(CPoint_d(lR.l+0.5,lR.b));
            pGC->Path().MoveTo(CPoint_d(lR.r-0.5,lR.t));
            pGC->Path().LineTo(CPoint_d(lR.r-0.5,lR.b));
            pGC->StrokePath();
            img::CLinearGradient lPattern3(CPoint_d(lR.l,lR.t),CPoint_d(lR.l,lR.b));
            lPattern3.AddStop(img::rgb8(186,186,186),0.0);
            lPattern3.AddStop(img::rgb8(121,121,121),0.5);
            lPattern3.AddStop(img::rgb8(150,150,150),1.0);
            pGC->SetSource(lPattern3);
            pGC->Path().MoveTo(CPoint_d(lR.l+1.5,lR.t));
            pGC->Path().LineTo(CPoint_d(lR.l+1.5,lR.b));
            pGC->Path().MoveTo(CPoint_d(lR.r-1.5,lR.t));
            pGC->Path().LineTo(CPoint_d(lR.r-1.5,lR.b));
            pGC->StrokePath();
        }

        pGC->SetSource(mColors.mText);
        pGC->SetFont(lFont);
        pGC->SetSource(img::rgb8(185,185,185));
        pGC->DrawText(CPoint_d(lR.l+lR.w()/2,lR.b-lFont->GetHeight()/2-4),pI->mText,img::ETextPos::CENTER);
        pGC->SetSource({0.0,0.0,0.0});
        pGC->DrawText(CPoint_d(lR.l+lR.w()/2,lR.b-lFont->GetHeight()/2-5),pI->mText,img::ETextPos::CENTER);

        if(pI->mIcon)
        {
            pI->mIcon->Draw(pGC,CPoint_d(lR.l+(lR.w()-pT->GetIconSize())/2,
                lR.t+(lR.h()-lFont->GetHeight()-5-pT->GetIconSize())/2),
                pT->GetIconSize());
        }
    }
    else
    {
        CImageMatrix *lUsed;
        CRect_d lR;

        if(pT->GetStyle(TABBOX_TOP))
        {
            if(pF&DRAW_SELECTED)
            {
                lR={pR.l,pR.t,pR.r,pR.b-4};
                lUsed=mTab.Get(mColors.mBase);
            }
            else
            {
                lR={pR.l,pR.t+2,pR.r,pR.b-4};
                lUsed=mTab.Get(mColors.mInactive);
            }
        }
        else
        {
            if(pF&DRAW_SELECTED)
            {
                lR={pR.l,pR.t+4,pR.r,pR.b};
                lUsed=mTabInvert.Get(mColors.mBase);
            }
            else
            {
                lR={pR.l,pR.t+4,pR.r,pR.b-2};
                lUsed=mTabInvert.Get(mColors.mInactive);
            }
        }

        lUsed->Draw(pGC,lR);

        pGC->SetSource(mColors.mText);
        pGC->SetFont(lFont);
        pGC->DrawText(CPoint_d(lR.l+9,(lR.t+lR.b-lFont->GetHeight())/2),pI->mText);
    }
}

void CCairoTheme::PrepareToolBar(CToolBar *pM)
{
    pM->SetBackColor({1.0,1.0,1.0});
    pM->SetPaintMode(CWindow::EPaintMode::NORMAL);
}

void CCairoTheme::DrawToolBar(img::CGC *pGC,CToolBar *pT,EDrawStyle)
{
    if(!mInit) Init();

    CRect_d lTLRect;///\todo =pT->GetTopLevelRect();
    img::CLinearGradient lBasePattern(CPoint_d(0,-lTLRect.t-22),CPoint_d(0,-lTLRect.t-22+100));
    lBasePattern.AddStop(img::rgb8(197,197,197),0.00);
    lBasePattern.AddStop(img::rgb8(170,170,170),0.56);
    lBasePattern.AddStop(img::rgb8(170,170,170),1.0);
    pGC->SetSource(lBasePattern);
    pGC->Paint();
/*
    img::CLinearGradient lPattern(CPoint_d(pR.l,pR.t),CPoint_d(pR.l,pR.b));
    lPattern.AddStop(img::rgb8(210,210,210),0.0);
    lPattern.AddStop(img::rgb8(194,194,194),0.33);
    lPattern.AddStop(img::rgb8(164,164,164),0.66);
    lPattern.AddStop(img::rgb8(148,148,148),1.0);
    pGC->SetSource(lPattern);
    Path().RoundRect(pGC,CRect_d(pR.l+5,pR.t+1,pR.r-5,pR.b-1),5);
    pGC->FillPath();
*/
}

void CCairoTheme::DrawToolBarItem(img::CGC *pGC,const CRect_d &pR,CToolBar*,PMenuItem pI,EDrawStyle pF)
{
    if(pI->IsSeparator()) return;
    if(pI->IsWindow())
    {
        pI->GetWindow()->Show();
        return;
    }

    if(!mInit) Init();

    CPoint_d lMiddle=pR.Center();

    img::CLinearGradient lPattern1(CPoint_d(0,pR.t+2),CPoint_d(0,pR.b-2));
    img::CLinearGradient lPattern2(CPoint_d(0,pR.t+2),CPoint_d(0,pR.b-2));

    if(pF&DRAW_HOVER)
    {
        lPattern1.AddStop(img::rgb8(140,178,215),0.0);
        lPattern1.AddStop(img::rgb8(194,234,255),1.0);
        lPattern2.AddStop(img::rgb8(85,140,210),0.0);
        lPattern2.AddStop(img::rgb8(145,220,252),1.0);
    }
    else if(pI->IsChecked())
    {
        lPattern1.AddStop(img::rgb8(225,188,120),0.0);
        lPattern1.AddStop(img::rgb8(255,234,174),1.0);
        lPattern2.AddStop(img::rgb8(210,140,85),0.0);
        lPattern2.AddStop(img::rgb8(252,220,145),1.0);
    }
    else
    {
        lPattern1.AddStop(img::rgb8(235,235,235),0.0);
        lPattern1.AddStop(img::rgb8(255,255,255),1.0);
        lPattern2.AddStop(img::rgb8(180,180,180),0.0);
        lPattern2.AddStop(img::rgb8(240,240,240),1.0);
    }

    double lRadius=9.0;

    pGC->SetSource(lPattern1);
    pGC->Path().Reset();
    if(pF&DRAW_LEFT)
    {
        pGC->Path().MoveTo(CPoint_d(pR.l+3,pR.t));
        pGC->Path().Arc(CPoint_d(pR.l+3,pR.t+3),3,3*M_PI/2,M_PI);
        pGC->Path().LineTo(CPoint_d(pR.l,lMiddle.y+lRadius));
        pGC->Path().Arc(CPoint_d(pR.l+lRadius,lMiddle.y+lRadius),lRadius,M_PI,3*M_PI/2);
    }
    else
    {
        pGC->Path().MoveTo(CPoint_d(pR.l,pR.t));
        pGC->Path().LineTo(CPoint_d(pR.l,lMiddle.y));
    }
    if(pF&DRAW_RIGHT)
    {
        pGC->Path().LineTo(CPoint_d(pR.r-lRadius,lMiddle.y));
        pGC->Path().Arc(CPoint_d(pR.r-lRadius,lMiddle.y-lRadius),lRadius,M_PI/2,0);
        pGC->Path().LineTo(CPoint_d(pR.r,pR.t+3));
        pGC->Path().Arc(CPoint_d(pR.r-3,pR.t+3),3,0,-M_PI/2);
    }
    else
    {
        pGC->Path().LineTo(CPoint_d(pR.r,lMiddle.y));
        pGC->Path().LineTo(CPoint_d(pR.r,pR.t));
    }
    pGC->Path().Close();
    pGC->FillPath();

    pGC->SetSource(lPattern2);
    pGC->Path().Reset();
    if(pF&DRAW_LEFT)
    {
        pGC->Path().MoveTo(CPoint_d(pR.l+3,pR.b));
        pGC->Path().Arc(CPoint_d(pR.l+3,pR.b-3),3,M_PI/2,M_PI);
        pGC->Path().LineTo(CPoint_d(pR.l,lMiddle.y+lRadius));
        pGC->Path().Arc(CPoint_d(pR.l+lRadius,lMiddle.y+lRadius),lRadius,M_PI,3*M_PI/2);
    }
    else
    {
        pGC->Path().MoveTo(CPoint_d(pR.l,pR.b));
        pGC->Path().LineTo(CPoint_d(pR.l,lMiddle.y));
    }
    if(pF&DRAW_RIGHT)
    {
        pGC->Path().LineTo(CPoint_d(pR.r-lRadius,lMiddle.y));
        pGC->Path().Arc(CPoint_d(pR.r-lRadius,lMiddle.y-lRadius),lRadius,M_PI/2,0);
        pGC->Path().LineTo(CPoint_d(pR.r,pR.b-3));
        pGC->Path().Arc(CPoint_d(pR.r-3,pR.b-3),3,0,M_PI/2);
    }
    else
    {
        pGC->Path().LineTo(CPoint_d(pR.r,lMiddle.y));
        pGC->Path().LineTo(CPoint_d(pR.r,pR.b));
    }
    pGC->Path().Close();
    pGC->FillPath();

    pGC->Path().Reset();
    CPoint_d lStart;
    if(pF&DRAW_LEFT)
    {
        lStart={pR.l+2.5,pR.b+0.5};
        pGC->Path().MoveTo(CPoint_d(pR.l+2.5,pR.b+0.5));
        pGC->Path().Arc(CPoint_d(pR.l+2.5,pR.b-2.5),3,M_PI/2,M_PI);
        pGC->Path().LineTo(CPoint_d(pR.l-0.5,pR.t+2.5));
        pGC->Path().Arc(CPoint_d(pR.l+2.5,pR.t+2.5),3,M_PI,3*M_PI/2);
    }
    else
    {
        lStart={pR.l-0.5,pR.b+0.5};
        pGC->Path().MoveTo(CPoint_d(pR.l-0.5,pR.t-0.5));
    }
    if(pF&DRAW_RIGHT)
    {
        pGC->Path().LineTo(CPoint_d(pR.r-2.5,pR.t-0.5));
        pGC->Path().Arc(CPoint_d(pR.r-2.5,pR.t+2.5),3,-M_PI/2,0);
        pGC->Path().LineTo(CPoint_d(pR.r+0.5,pR.b-2.5));
        pGC->Path().Arc(CPoint_d(pR.r-2.5,pR.b-2.5),3,0,M_PI/2);
    }
    else
    {
        pGC->Path().LineTo(CPoint_d(pR.r+0.5,pR.t-0.5));
        pGC->Path().MoveTo(CPoint_d(pR.r+0.5,pR.b+0.5));
    }
    pGC->Path().LineTo(lStart);
    pGC->SetLineWidth(1.0);
    pGC->SetSource(img::rgb8(122,122,122));
    pGC->StrokePath();

    pGC->Path().Reset();
    if(pF&DRAW_LEFT)
    {
        pGC->Path().MoveTo(CPoint_d(pR.l+2.5,pR.t-1.5));
    }
    else
    {
        pGC->Path().MoveTo(CPoint_d(pR.l-0.5,pR.t-1.5));
    }
    if(pF&DRAW_RIGHT)
    {
        pGC->Path().LineTo(CPoint_d(pR.r-2.5,pR.t-1.5));
    }
    else
    {
        pGC->Path().LineTo(CPoint_d(pR.r+0.5,pR.t-1.5));
    }
    pGC->SetLineWidth(1.0);
    pGC->SetSource(img::rgb8(170,170,170));
    pGC->StrokePath();

    pGC->Path().Reset();
    if(pF&DRAW_LEFT)
    {
        pGC->Path().MoveTo(CPoint_d(pR.l+2.5,pR.b+1.5));
    }
    else
    {
        pGC->Path().MoveTo(CPoint_d(pR.l-0.5,pR.b+1.5));
    }
    if(pF&DRAW_RIGHT)
    {
        pGC->Path().LineTo(CPoint_d(pR.r-2.5,pR.b+1.5));
    }
    else
    {
        pGC->Path().LineTo(CPoint_d(pR.r+0.5,pR.b+1.5));
    }
    pGC->SetLineWidth(1.0);
    pGC->SetSource(img::rgb8(199,199,199));
    pGC->StrokePath();

    if(!(pF&DRAW_LEFT))
    {
        pGC->SetSource(img::rgba8(0,0,0,20));
        pGC->Path().MoveTo(CPoint_d(pR.l-0.5,pR.t));
        pGC->Path().LineTo(CPoint_d(pR.l-0.5,pR.b));
        pGC->StrokePath();
    }

    if(pI->GetIcon())
    {
        pI->GetIcon()->Draw(pGC,CPoint_d(
            (pR.l+pR.r)/2-CIcon::SMALL/2,
            (pR.t+pR.b)/2-CIcon::SMALL/2),
            CIcon::SMALL);
    }
}

void CCairoTheme::DrawMenuBarItem(img::CGC *pGC,const CRect_d &pR,CMenuBar *pM,PMenuItem pI,EDrawStyle)
{
    if(pM->GetStyle()&CMenuBar::STYLE_POPUP)
    {
        if(pI->IsDefault())
            pGC->SetFont(mMenuBoldFont);
        else
            pGC->SetFont(mMenuFont);

        if(pM->GetSelected()==pI)
        {
            img::CLinearGradient lPattern(CPoint_d(pR.l,pR.t),CPoint_d(pR.l,pR.b));
            lPattern.AddStop(img::rgb8(30,115,200),0.0);
            lPattern.AddStop(img::rgb8(19,77,134),1.0);
            pGC->SetSource(lPattern);
            pGC->Path().RoundRect(CRect_d(pR.l+2,pR.t,pR.r-2,pR.b),3);
            pGC->FillPath();
            pGC->SetSource({1.0,1.0,1.0});
        }
        else
        {
            pGC->SetSource(gConfig.mColors.Get(L"normal_text"));
        }

        if(pI->IsSeparator())
        {
            pGC->Path().MoveTo(CPoint_d(3,pR.t+2));
            pGC->Path().LineTo(CPoint_d(pR.r-3,pR.t+2));
        }
        else
        {
            std::wstring lText=pI->GetText();
            if(pI->GetAccelText().length())
            {
                lText+=L" (";
                lText+=pI->GetAccelText();
                lText+=L")";
            }
            if(pM->GetStyle(CMenuBar::STYLE_COMMENT)&&pI->GetComment().length())
            {
                pGC->DrawText(CPoint_d(pM->GetTextX(),(pR.t+pR.b)/2+2),lText,img::ETextPos::BOTTOM);
                if(pM->GetSelected()==pI)
                    pGC->SetSource(img::CColor(L"lightsteelblue"));
                else
                    pGC->SetSource(img::CColor(L"steelblue"));
                pGC->SetFont(mSmallFont);
                pGC->DrawText(CPoint_d(pM->GetTextX(),(pR.t+pR.b)/2),pI->GetComment());
            }
            else
            {
                pGC->DrawText(CPoint_d(pM->GetTextX(),(pR.t+pR.b)/2),lText,img::ETextPos::VCENTER);
            }
        }

        if(pI->IsSubMenu())
        {
            if(pM->GetSelected()==pI)
                pGC->SetSource({1.0,1.0,1.0});
            else
                pGC->SetSource(img::rgb8(0,0,0));
            DrawArrow(pGC,CPoint_d(pR.r-9.0,pR.t+pR.h()/2),ARROW_RIGHT);
        }

        if(pI->GetIcon())
        {
            pI->GetIcon()->Draw(pGC,CPoint_d(5,pR.t+2),pM->GetIconSize());
        }
    }
    else
    {
        pGC->SetFont(mMenuBoldFont);

        if(pM->GetSelected()==pI)
        {
            img::CLinearGradient lPattern(CPoint_d(pR.l,pR.t),CPoint_d(pR.l,pR.b));
            lPattern.AddStop(img::rgb8(30,115,200),0.0);
            lPattern.AddStop(img::rgb8(19,77,134),1.0);
            pGC->SetSource(lPattern);
            pGC->Path().RoundRect(CRect_d(pR.l,pR.t,pR.r,pR.b),3);
            pGC->FillPath();
            pGC->SetSource({1.0,1.0,1.0});
        }
        else
        {
            pGC->SetSource(img::rgb8(19,77,134));
        }

        if(!pI->IsSeparator())
        {
            pGC->DrawText(CPoint_d(pR.l+5,pR.t),pI->GetText());
        }
    }
}

void CCairoTheme::DrawTreeBox(img::CGC*,CTreeBox*,EDrawStyle)
{
    if(!mInit) Init();
}

void CCairoTheme::DrawScrollBarCursor(img::CGC *pGC,const CRect_d &pR,bool pVertical,bool pActive)
{
    pGC->SetSource(img::CColor(0.1,0.1,0.1));
    pGC->SetLineCap(img::ELineCap::ROUND);
    pGC->SetLineWidth(7.0);
    
    if(pVertical)
    {
        pGC->Path().MoveTo(pR.l+4.5,(pR.t+pR.b)/2);
        pGC->Path().LineTo(pR.r-4.5,(pR.r+pR.b)/2);
    }
    else
    {
        pGC->Path().MoveTo((pR.l+pR.r)/2,pR.t+4.5);
        pGC->Path().LineTo((pR.l+pR.r)/2,pR.b-4.5);
    }
}

void CCairoTheme::DrawCheckBoxBox(img::CGC *pGC,const CRect_d &pR,bool pChecked)
{
    if(!mInit) Init();

    if(pChecked)
        pGC->DrawImage(pR.Center()-mCheckBoxOn.GetSize()/2,
                    mCheckBoxOn.Get(mColors.mBase));
    else
        pGC->DrawImage(pR.Center()-mCheckBoxOn.GetSize()/2,
                    mCheckBoxOff.Get(mColors.mInactive));
}

void CCairoTheme::DrawCursor(img::CGC *pGC,const CRect_d &pRect)
{
    pGC->SetSource(mColors.mText);

    pGC->SetLineWidth(1.0);
    pGC->Path().MoveTo(CPoint_d(floor(pRect.l)+0.5,pRect.t));
    pGC->Path().LineTo(CPoint_d(floor(pRect.l)+0.5,pRect.b));
    pGC->StrokePath();
}

void CCairoTheme::DrawHandle(img::CGC*,const CRect_d &pR,bool pHover)
{
    if(pHover)
    {
        for(int y=(int)pR.t+2,i=0;y<(int)pR.b-4;y+=3,i++)
        {
//          int x=(i%2)?(pR.l+4):(pR.l+1);

//          pGC->SetSource(img::rgb8(60,60,85));
//          pGC->DrawLine(CPoint_d(x,y),CPoint_d(x+1,y));
//          pGC->PutPixel(CPoint_d(x,y+1));
//          pGC->SetSource(img::rgb8(120,120,170));
//          pGC->PutPixel(CPoint_d(x+1,y+1));
//          pGC->SetSource(img::rgb8(180,180,255));
//          pGC->DrawLine(CPoint_d(x+1,y+2),CPoint_d(x+2,y+2));
//          pGC->PutPixel(CPoint_d(x+2,y+1));
        }
    }
    else
    {
        for(int y=(int)pR.t+2,i=0;y<(int)pR.b-4;y+=3,i++)
        {
//          int x=(i%2)?(pR.l+4):(pR.l+1);

//          pGC->SetSource(GREY65);
//          pGC->DrawLine(CPoint_d(x,y),CPoint_d(x+1,y));
//          pGC->PutPixel(CPoint_d(x,y+1));
//          pGC->SetSource(GREY75);
//          pGC->PutPixel(CPoint_d(x+1,y+1));
//          pGC->SetSource(GREY85);
//          pGC->DrawLine(CPoint_d(x+1,y+2),CPoint_d(x+2,y+2));
//          pGC->PutPixel(CPoint_d(x+2,y+1));
        }
    }
}

void CCairoTheme::PrepareHandleBar(CWindow *pW)
{
    pW->SetBackNone();
    pW->SetPaintMode(CWindow::EPaintMode::NORMAL);
}

void CCairoTheme::DrawHandleBar(img::CGC *pGC,const CRect_d &pR,const std::wstring &pText,
                                    EDecoFlags pFlags,EDecoFlags pActive)
{
    DrawSeparationLine(pGC,CPoint_d(pR.l,pR.t),CPoint_d(pR.r,pR.t));

    img::CLinearGradient lPattern(CPoint_d(pR.l,pR.t),CPoint_d(pR.l,pR.b));
    lPattern.AddStop(img::rgb8(205,209,217),0.0);
    lPattern.AddStop(img::rgb8(177,183,196),0.125);
    lPattern.AddStop(img::rgb8(136,150,175),0.875);
    lPattern.AddStop(img::rgb8(127,141,166),1.0);
    pGC->SetSource(lPattern);
    pGC->Paint();
    pGC->SetSource({0.0,0.0,0.0});
    pGC->SetStockFont((pFlags&DECO_ACTIVE)?L"smallbold":L"small");
    pGC->DrawText(CPoint_d(pR.l+10,(pR.t+pR.b)/2),pText,img::ETextPos::VCENTER);

    pGC->SetSource(img::rgb8(177,183,196));
    pGC->SetLineWidth(1.0);
    pGC->Path().MoveTo(CPoint_d(pR.l,pR.b-0.5));
    pGC->Path().LineTo(CPoint_d(pR.r,pR.b-0.5));
    pGC->StrokePath();

/*  img::CLinearGradient lCirclePattern(CPoint_d(pR.l,pR.t),CPoint_d(pR.l,pR.b));
    lCirclePattern.AddStop(img::rgb8(102,104,109),0.0);
//  lCirclePattern.AddStop(img::rgb8(88,91,98),0.125);
//  lCirclePattern.AddStop(img::rgb8(68,75,87),0.875);
    lCirclePattern.AddStop(img::rgb8(63,71,83),1.0);
    pGC->SetSource(&lCirclePattern);
*/
    CPoint_d lCenter(pR.r-12,(pR.t+pR.b)/2);
    if(pActive==DECO_CLOSE)
    {
        pGC->DrawImage(lCenter-7,mDecoButtonRed);
        pGC->SetSource(img::rgba8(0,0,0,200));
    }
    else
    {
        pGC->SetSource(img::rgba8(0,0,0,100));
        pGC->Path().Reset();
        pGC->Path().Arc(lCenter,6);
        pGC->SetLineWidth(0.5);
        pGC->StrokePath();
    }
    pGC->Path().MoveTo(CPoint_d(lCenter.x-3,lCenter.y-3));
    pGC->Path().LineTo(CPoint_d(lCenter.x+3,lCenter.y+3));
    pGC->Path().MoveTo(CPoint_d(lCenter.x-3,lCenter.y+3));
    pGC->Path().LineTo(CPoint_d(lCenter.x+3,lCenter.y-3));
    pGC->SetLineWidth(2.0);
    pGC->StrokePath();

    lCenter.x-=18;
    if(pActive==DECO_DOCK)
    {
        pGC->DrawImage(lCenter-7,mDecoButtonBlue);
        pGC->SetSource(img::rgba8(0,0,0,200));
    }
    else
    {
        pGC->SetSource(img::rgba8(0,0,0,100));
        pGC->Path().Reset();
        pGC->Path().Arc(lCenter,6);
        pGC->SetLineWidth(0.5);
        pGC->StrokePath();
    }
    pGC->Path().MoveTo(CPoint_d(lCenter.x+3,lCenter.y+3));
    pGC->Path().LineTo(CPoint_d(lCenter.x,lCenter.y));
    pGC->SetLineWidth(2.0);
    pGC->StrokePath();
    pGC->Path().MoveTo(CPoint_d(lCenter.x-3,lCenter.y-3));
    pGC->Path().LineTo(CPoint_d(lCenter.x-3,lCenter.y+3));
    pGC->Path().LineTo(CPoint_d(lCenter.x+3,lCenter.y-3));
    pGC->Path().LineTo(CPoint_d(lCenter.x-3,lCenter.y-3));
    pGC->FillPath();

    lCenter.x-=18;
    if(pActive==DECO_MIN)
    {
        pGC->DrawImage(lCenter-7,mDecoButtonYellow);
        pGC->SetSource(img::rgba8(0,0,0,100));
    }
    else
    {
        pGC->SetSource(img::rgba8(0,0,0,100));
        pGC->Path().Reset();
        pGC->Path().Arc(lCenter,6);
        pGC->SetLineWidth(0.5);
        pGC->StrokePath();
    }
    pGC->Path().MoveTo(CPoint_d(lCenter.x,lCenter.y-4));
    pGC->Path().LineTo(CPoint_d(lCenter.x,lCenter.y));
    pGC->SetLineWidth(2.0);
    pGC->StrokePath();
    pGC->Path().MoveTo(CPoint_d(lCenter.x-4,lCenter.y));
    pGC->Path().LineTo(CPoint_d(lCenter.x+4,lCenter.y));
    pGC->Path().LineTo(CPoint_d(lCenter.x,lCenter.y+4));
    pGC->Path().LineTo(CPoint_d(lCenter.x-4,lCenter.y));
    pGC->FillPath();
}

void CCairoTheme::DrawRulerField(img::CGC *pGC,const CRect_d &pR,const std::wstring &pS,bool pUnder,bool /*pVertical*/)
{
    ///\todo use pVertical
    if(pUnder)
    {
        img::CLinearGradient lPattern(CPoint_d(0,pR.t),CPoint_d(0,pR.b-1));
        lPattern.AddStop(img::rgb8(211,220,234),0.00);
        lPattern.AddStop(img::rgb8(104,162,224),0.5);
        lPattern.AddStop(img::rgb8(170,222,255),0.85);
        lPattern.AddStop(img::rgb8(193,247,255),1.0);
        pGC->SetSource(lPattern);
        pGC->Path().Rect(pR.TopLeft(),CSize_d(pR.w(),pR.h()-1));
        pGC->FillPath();
    }

    pGC->SetSource(img::rgba8(0,0,0,50));
    pGC->Path().MoveTo(CPoint_d(pR.r+0.5,pR.t));
    pGC->Path().LineTo(CPoint_d(pR.r+0.5,pR.b-1));
    pGC->SetLineWidth(1.0);
    pGC->StrokePath();

    pGC->SetSource(mColors.mText);
    pGC->SetFont(mFont);
    pGC->DrawText(CPoint_d(pR.l+5,(pR.t+pR.b)/2),pS);
}

void CCairoTheme::DrawRulerFieldHL(img::CGC *pGC,const CRect_d &pR,const std::wstring &pS,const img::CColor &pColor,
                                   bool /*pVertical*/)
{
    img::CLinearGradient lPattern(CPoint_d(0,pR.t),CPoint_d(0,pR.b-1));
    lPattern.AddStop(pColor.GetLighter(30),0.00);
    lPattern.AddStop(pColor.GetDarker(10),0.5);
    lPattern.AddStop(pColor.GetLighter(25),0.85);
    lPattern.AddStop(pColor.GetLighter(40),1.0);
    pGC->SetSource(lPattern);
    pGC->Path().Rect(pR.TopLeft(),pR.Size());
    pGC->FillPath();

    pGC->SetSource(img::rgba8(0,0,0,50));
    pGC->Path().MoveTo(CPoint_d(pR.r+0.5,pR.t));
    pGC->Path().LineTo(CPoint_d(pR.r+0.5,pR.b-1));
    pGC->SetLineWidth(1.0);
    pGC->StrokePath();

    pGC->SetSource(mColors.mText);
    pGC->SetFont(mFont);
    pGC->DrawText(CPoint_d(pR.l+5,(pR.t+pR.b)/2),pS);
}

void CCairoTheme::DrawLabel(img::CGC *pGC,const CPoint_d &pP,const std::wstring &pS)
{
    pGC->SetSource(mColors.mText);
    pGC->SetFont(mBoldFont);
    pGC->DrawText(pP,pS);
}

void CCairoTheme::DrawThinBar(img::CGC *pGC,const CRect_d &pR)
{
    if(!mInit) Init();

    pGC->DrawImageTiled(pR,pR.TopLeft(),mTabBase.Get(mColors.mBase));
}

void CCairoTheme::DrawShadow(img::CGC *pGC,const CRect_d &pR)
{
    if(!mInit) Init();

//    CSize_d lSize=pR.Size();

//    pGC->Composite(pR.TopLeft(),CSize_d(lSize.x,min(lSize.y,15.0)),
//        mBlackPicture,CPoint_d(0,0),CSize_d(nUndefined),mShadow,CPoint_d(50,1515));
//    pGC->Composite(pR.TopLeft(),CSize_d(min(lSize.x,15.0),lSize.y),
//        mBlackPicture,CPoint_d(0,0),CSize_d(nUndefined),mShadow,CPoint_d(1515,50));
}

void CCairoTheme::DrawSplitItem(img::CGC*,const CRect_d&,int /*pType*/)
{
    ///\todo this
    if(!mInit) Init();

//    if(pType==SPLIT_VERT)
//    {
////        pGC->SetSource(gConfig.mColors.Get(L"split_back"));
////        pGC->FillRect(pR);
//      pGC->SetSource(gConfig.mColors.Get(L"split_divider"));
//      pGC->DrawLine(CPoint_d(pR.l+1,(pR.t+pR.b)/2-20),
//                CPoint_d(pR.l+1,(pR.t+pR.b)/2+20));
//      pGC->SetSource(gConfig.mColors.Get(L"normal_text"));
//      pGC->DrawLine(CPoint_d(pR.l+2,(pR.t+pR.b)/2-20),
//                CPoint_d(pR.l+2,(pR.t+pR.b)/2+20));
//    }
//    else
//    {
////        pGC->SetSource(gConfig.mColors.Get(L"split_back"));
////        pGC->FillRect(pR);
//      pGC->SetSource(gConfig.mColors.Get(L"split_divider"));
//      pGC->DrawLine(CPoint_d((pR.l+pR.r)/2-20,pR.t+1),
//                CPoint_d((pR.l+pR.r)/2+20,pR.t+1));
//      pGC->SetSource(gConfig.mColors.Get(L"normal_text"));
//      pGC->DrawLine(CPoint_d((pR.l+pR.r)/2-20,pR.t+2),
//                CPoint_d((pR.l+pR.r)/2+20,pR.t+2));
//    }
}

void CCairoTheme::DrawSeparationLine(img::CGC *pGC,const CPoint_d &p1,
                                                const CPoint_d &p2)
{
    pGC->SetSource({0.65,0.65,0.65});
    pGC->Path().MoveTo(p1);
    pGC->Path().LineTo(p2);
    pGC->StrokePath();
    CPoint_d lOffset;
    if(std::abs(p2.x-p1.x)>std::abs(p2.y-p1.y)) //horizontal
    {
        lOffset={0,1};
    }
    else
    {
        lOffset={1,0};
    }
    pGC->SetSource({0.9,0.9,0.9});
    pGC->Path().MoveTo(p1+lOffset);
    pGC->Path().LineTo(p2+lOffset);
    pGC->StrokePath();
}

void CCairoTheme::PrepareDecoration(CWindow *pW)
{
    pW->SetBackColor(img::CColor(0,0,0,0));
    pW->SetPaintMode(CWindow::EPaintMode::NORMAL);
}

void CCairoTheme::DrawDecoButton(img::CGC *pGC,const img::CPicture &pImage,const CRect_d &pR)
{
    CSize_d lS(pImage.Size());
    pGC->DrawImagePart(CRect_d(2,0,3,lS.y),CPoint_d(pR.l,pR.t),pImage);
    pGC->DrawImagePart(CRect_d(lS.x-3,0,lS.x-2,lS.y),CPoint_d(pR.r-1,pR.t),pImage);
    pGC->DrawImageRect(CRect_d(3,0,lS.x-3,lS.y),CRect_d(pR.l+1,pR.t,pR.r-1,pR.b),
                            pImage);
}

void CCairoTheme::DrawDecoration(img::CGC *pGC,const CRect_d &pR,const std::wstring &pTitle,EDecoFlags pFlags)
{
    if(!mInit) Init();
    if(!mDecoInit) InitDeco();

    pGC->DrawImageScaled(CPoint_d(pR.l+9,pR.t),CSize_d(pR.w()-18,25),mDeco.mT);
//  pGC->DrawImageScaled(CPoint_d(pR.l,pR.t+26),CSize_d(5,pR.h()-32),mDeco.mL);
//  pGC->DrawImageScaled(CPoint_d(pR.r-5,pR.t+26),CSize_d(5,pR.h()-32),mDeco.mR);
//  pGC->DrawImageScaled(CPoint_d(pR.l+7,pR.b-6),CSize_d(pR.w()-14,7),mDeco.mB);

    pGC->SetSource(img::rgb8(50,50,50));
    pGC->Path().MoveTo(CPoint_d(pR.l+0.5,pR.t+25));
    pGC->Path().LineTo(CPoint_d(pR.l+0.5,pR.b-0.5));
    pGC->Path().LineTo(CPoint_d(pR.r-0.5,pR.b-0.5));
    pGC->Path().LineTo(CPoint_d(pR.r-0.5,pR.t+25));
    pGC->SetLineWidth(1.0);
    pGC->StrokePath();

    pGC->DrawImage(CPoint_d(pR.l,pR.t),mDeco.mTL);
    pGC->DrawImage(CPoint_d(pR.r-9,pR.t),mDeco.mTR);
//  pGC->DrawImage(CPoint_d(pR.l,pR.b-6),mDeco.mBL);
//  pGC->DrawImage(CPoint_d(pR.r-9,pR.b-6),mDeco.mBR);

    CRect_d lBut(pR.r-30,pR.t,pR.r-12,25);
    if(pFlags&DECO_CLOSE)
    {
        EDecoState lState=DECO_STATE_INACTIVE;

        if(pFlags&DECO_ACTIVE)
            lState=DECO_STATE_NORMAL;

        if(pFlags&DECO_MOUSEIN)
            lState=DECO_STATE_HOVER;

        DrawDecoButton(pGC,mDeco.mButtons[DECO_BUTTON_CLOSE][lState],lBut);

        CPoint_d lCenter((lBut.l+lBut.r)/2,pR.t+8);

        pGC->SetSource(img::rgba8(50,50,50,130));
        pGC->Path().MoveTo(CPoint_d(lCenter.x-3,lCenter.y-3));
        pGC->Path().LineTo(CPoint_d(lCenter.x+3,lCenter.y+3));
        pGC->Path().MoveTo(CPoint_d(lCenter.x-3,lCenter.y+3));
        pGC->Path().LineTo(CPoint_d(lCenter.x+3,lCenter.y-3));
        pGC->SetLineWidth(2.0);
        pGC->StrokePath();

        lBut+=CPoint_d(-18,0);
    }
    if(pFlags&DECO_MIN)
    {
        EDecoState lState=DECO_STATE_INACTIVE;

        if(pFlags&DECO_ACTIVE)
            lState=DECO_STATE_NORMAL;

        if(pFlags&DECO_MOUSEIN)
            lState=DECO_STATE_HOVER;

        DrawDecoButton(pGC,mDeco.mButtons[DECO_BUTTON_MIN][lState],lBut);

        CPoint_d lCenter((lBut.l+lBut.r)/2,pR.t+8);

        pGC->SetSource(img::rgba8(50,50,50,130));
        pGC->Path().MoveTo(CPoint_d(lCenter.x-3,lCenter.y));
        pGC->Path().LineTo(CPoint_d(lCenter.x+3,lCenter.y));
        pGC->SetLineWidth(2.0);
        pGC->StrokePath();

        lBut+=CPoint_d(-18,0);
    }
    if(pFlags&DECO_MAX)
    {
        EDecoState lState=DECO_STATE_INACTIVE;

        if(pFlags&DECO_ACTIVE)
            lState=DECO_STATE_NORMAL;

        if(pFlags&DECO_MOUSEIN)
            lState=DECO_STATE_HOVER;

        DrawDecoButton(pGC,mDeco.mButtons[DECO_BUTTON_MAX][lState],lBut);

        CPoint_d lCenter((lBut.l+lBut.r)/2,pR.t+8);

        pGC->SetSource(img::rgba8(50,50,50,130));
        pGC->Path().MoveTo(CPoint_d(lCenter.x-3,lCenter.y));
        pGC->Path().LineTo(CPoint_d(lCenter.x+3,lCenter.y));
        pGC->Path().MoveTo(CPoint_d(lCenter.x,lCenter.y+3));
        pGC->Path().LineTo(CPoint_d(lCenter.x,lCenter.y-3));
        pGC->SetLineWidth(2.0);
        pGC->StrokePath();

        lBut+=CPoint_d(-18,0);
    }
    if(pFlags&DECO_DOCK)
    {
        EDecoState lState=DECO_STATE_INACTIVE;

        if(pFlags&DECO_ACTIVE)
            lState=DECO_STATE_NORMAL;

        if(pFlags&DECO_MOUSEIN)
            lState=DECO_STATE_HOVER;

        DrawDecoButton(pGC,mDeco.mButtons[DECO_BUTTON_DOCK][lState],lBut);

        CPoint_d lCenter((lBut.l+lBut.r)/2,pR.t+8);

        pGC->SetSource(img::rgba8(50,50,50,130));
        pGC->Path().MoveTo(CPoint_d(lCenter.x+3,lCenter.y-3));
        pGC->Path().LineTo(CPoint_d(lCenter.x,lCenter.y));
        pGC->SetLineWidth(2.0);
        pGC->StrokePath();
        pGC->Path().MoveTo(CPoint_d(lCenter.x-3,lCenter.y+3));
        pGC->Path().LineTo(CPoint_d(lCenter.x-3,lCenter.y-3));
        pGC->Path().LineTo(CPoint_d(lCenter.x+3,lCenter.y+3));
        pGC->Path().LineTo(CPoint_d(lCenter.x-3,lCenter.y+3));
        pGC->FillPath();

        lBut+=CPoint_d(-18,0);
    }

/*
    pGC->Path().Rect(pR.TopLeft(),pR.Size());
    pGC->SetSource(img::CColor({0.0,0.0,0.0}));
    pGC->FillPath();
    CRect_d lBrightR(pR.l,pR.t+1,pR.r,pR.t+round(pR.h()/2));
    pGC->Path().Rect(lBrightR.TopLeft(),lBrightR.Size());
    img::CLinearGradient lPattern(CPoint_d(lBrightR.l,lBrightR.t),
                        CPoint_d(lBrightR.l,lBrightR.b));

    lPattern.AddStop(img::rgb8(122,122,122),0.0);
    lPattern.AddStop(img::rgb8(104,104,104),0.5);
    lPattern.AddStop(img::rgb8(78,78,78),1.0);
    pGC->SetSource(lPattern);
    pGC->FillPath();
*/
/*
    if(pFlags&DECO_ACTIVE)
    {
        img::CLinearGradient lLinePattern(CPoint_d(pR.l+15,pR.t),
                                        CPoint_d(pR.r,pR.t));
        lLinePattern.AddStop(img::CColor(0,0,0,1.0),0.0);
        lLinePattern.AddStop(img::CColor(0.5,0.5,0.2,1.0),1.0);
        pGC->SetSource(lLinePattern);
//      pGC->Path().Rect(pR.TopLeft(),pR.Size());
//      pGC->FillPath();
        pGC->Path().MoveTo(CPoint_d(pR.l+15,pR.b-7.5));
        pGC->Path().LineTo(CPoint_d(pR.r-5,pR.b-7.5));
        pGC->SetLineWidth(1.0);
        pGC->StrokePath();
    }
*/
    pGC->SetStockFont(L"nicemedium");
    CPoint_d lP(pR.l+10,pR.t+12);
    pGC->SetSource(img::rgb8(70,80,90));
    pGC->DrawText(CPoint_d(lP.x,lP.y+1),pTitle,img::ETextPos::VCENTER);
    pGC->SetSource(img::rgb8(240,240,240));
    pGC->DrawText(CPoint_d(lP.x,lP.y),pTitle,img::ETextPos::VCENTER);
}

CSize_d CCairoTheme::GetLabelSize(const std::wstring &pLabel)
{
    if(!mInit) Init();

    return CSize_d(mBoldFont->GetWidth(pLabel),mBoldFont->GetHeight());
}

CSize_d CCairoTheme::GetScrollBarButtonSize()
{
    if(!mInit) Init();
    return CSize_d(mVButton.GetSize().x,mVButton.GetSize().y);
}

int CCairoTheme::GetSliderSize()
{
    if(!mInit) Init();
    return (int)mHSliderArrow.GetSize().x;
}

CSize_d CCairoTheme::GetMicroButtonSize()
{
    return mMicroButton.GetSize();
}

double CCairoTheme::GetResizeBarWidth(EDrawStyle /*pStyle*/)
{
    return 4;
}

double CCairoTheme::GetAttachHandleWidth(EAttachFlags pFlags)
{
    if(pFlags&ATTACH_BAR)
        return 20;
    else
        return 10;
}

void CCairoTheme::SetBackground(CWindow *pWindow,int pType)
{
    if(!mInit) Init();

    switch(pType)
    {
    case BACKGROUND_TOOLTIP:
        pWindow->SetBackColor(img::rgb8(255,255,170));
        break;
    default:
        pWindow->SetBackNone();
    }
}

/*namespace gui*/ } /*namespace buola*/ }
